
//preload custom properties and events files for IDE Enviorment
if (jsx3.IDE) {
  jsx3.ide.loadTemplateCatalog("prop", "properties/catalog.xml", ux.megatron.ADDIN);
  jsx3.ide.loadTemplateCatalog("event", "modelevents/catalog.xml", ux.megatron.ADDIN);
}

//modify for fans of firebug,like Alan
if(window["console"] == null){
	window['console'] = {};
	console.log = function() {
        /* @JSC :: begin DEBUG */
        jsx3.log(Array.prototype.join.call(arguments, ","));
        /* @JSC :: end */
    }
}
/**
 * The top-level package.
 */
jsx3.lang.Package.definePackage("ux", function(ux) {
});

/**
 * The root package for all Megatron Addin UI classes.
 */
jsx3.lang.Package.definePackage("ux.megatron", function(megatron) {
});

/**
 * The main utility class of the Megatron Addin UI, containing most of the utility functions
 * to be used by plugin developers.
 */
jsx3.lang.Class.defineClass("ux.megatron.Main", null, null, function(main) {



    /**
     * {Object} An associative array containing the mappings between plugin package namespaces and their contextRoots
     * @private
     * @jsxobf-clobber
     */
    main.contextRoots = new Object();

    /**
     * {jsx3.app.Server} The current server object.  This allows individual plugin projects to set the server object when not being run
     * from the administrator project.
     * @private
     * @jsxobf-clobber
     */
    main.server = null;


    /**
     * NOTE: In ActiveMatrix 2.0, this function does NOT work, as the server is set before the addin is fully loaded (to
     *       resolve paths from the addin's dynamic property files). Will remain private until such time as this issue can be resolved.
     *
     * Allows plugin developers to programmatically set the server object for use in their project, if they are not running their
     * plugin from inside the administrator project.  The first call to this function will set the server object.  Successive calls
     * will be ignored.  In this fashion, the top-level project will set the server object, and code executed from dynamically
     * loaded plugins (from other projects) will not be able to incorrectly set this value when their project is not defining the
     * server object.
     *
     * @param serverObj {String | jsx3.app.Server} either the <code>jsx3.app.Server</code> object to use as the server context for
     *                  the application, of a string giving the name of the object (an eval() will be performed on this string to
     *                  get the <code>jsx3.app.Server</code> object).
     * @throws {ux.megatron.exception.InvalidServerException} if <code>serverObj</code> is not a valid <code>jsx3.app.Server</code>
     *         object or a <code>String</code> that can be evaluated to a valid <code>jsx3.app.Server</code> object.
     * @throws {jsx3.lang.Exception} if any unknown error occurs while setting the server object.  Known errors will always be
     *         displayed in an alert.
     *
     * @private
     */
    main.setServer = function(serverObj) {
        try {
            if (!this.server) {
                if (serverObj) {
                    if (typeof(serverObj) == "string") {
                        try {
                            this.server = jsx3.eval(serverObj);
                            if (!(this.server instanceof jsx3.app.Server)) {
                                this.server = null;
                                throw new ux.megatron.exception.InvalidServerException("The string " + serverObj + " cannot be evaluated to a valid jsx3.app.Server object");
                            }
                        } catch(ex) {
                            if (ex instanceof ux.megatron.exception.InvalidServerException) {
                                throw ex;
                            }
                            else {
                                this.server = null;
                                throw new ux.megatron.exception.InvalidServerException("Error evaluating " + serverObj + ". Cannot get a valid jsx3.app.Server object", jsx3.NativeError.wrap(ex));
                            }
                        }
                    }
                    else if (serverObj instanceof jsx3.app.Server) {
                        this.server = serverObj;
                    }
                    else {
                        throw new ux.megatron.exception.InvalidServerException("The argument to ux.megatron.Main.setServer() must be either a jsx3.app.Server object or a String");
                    }
                }
                else {
                    throw new ux.megatron.exception.InvalidServerException("The argument to ux.megatron.Main.setServer() is null or undefined");
                }
            }
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.setServer");
            if (ex instanceof ux.megatron.exception.InvalidServerException) {
                throw ex;
            }
            else {
                throw new jsx3.lang.Exception("Unknown exception while setting server object in ux.megatron.Main.setServer()", jsx3.NativeError.wrap(ex));
            }
        }

    }

    /**
     * Gets the application server for the ActiveMatrix Admin UI
     *
     * @return {jsx3.app.Server} the application server object.
     * @throws {ux.megatron.exception.ServerNotDefinedException} if no valid {jsx3.app.Server} object has been
     *         set
     */
    main.getServer = function() {
        if (this.server) {
            return this.server;
        }
        else {
            if (APP && APP.ux && APP.ux.megatron && (APP.ux.megatron instanceof jsx3.app.Server)) {
                this.server = APP.ux.megatron;
                return APP.ux.megatron;
            }
            else {
                throw new ux.megatron.exception.ServerNotDefinedException(" a call to ux.megatron.Main.setServer() is required.");
            }
        }
    };

    /**
     * Given an exception and an optional message, prints the exception to the logs
     *
     * @param ex {jsx3.lang.Exception} the exception to log
     * @param message {String} (optional) a message to prepend to the exception logging
     */
    main.logException = function(ex, message) {
        try {
            if (!ex.wasLogged) {
                ex.wasLogged = true;
                jsx3.util.Logger.GLOBAL.error((message) ? message : "An error occurred: ", jsx3.NativeError.wrap(ex));
            }
        } catch(e) {
            this.logException(new jsx3.lang.Exception("An error occurred while attempting to log an exception."), "Error logging exception: ");
        }
    }

    /**
     * Given a filename or path, resolves the URI to an image in the ActiveMatrix webapp contextRoot (the launch page).
     * This is the value you would use to access an image outside of GI (for example when setting the <code>src</code>
     * attribute of an <code>&lt;img&gt;</code> tag.
     *
     * @param strPath {String} the resolved (relative to the project) path MatrixAdmin addin to the desired image file
     *
     * @return {String} the path to the image file requested, relative to the ActiveMatrix webapp contextRoot (the
     *                  location of the browser document)
     */
    main.resolveImageRelativeToAdmin = function(strPath) {
        var path = "" + strPath;
        var idx = path.indexOf("addins");
        if(idx == -1) {
            path = "" + this.getServer().resolveURI(path);
            idx = path.indexOf("addins");
            if(idx == -1) {
                return strPath;
            }
        }
        return "../../" + path.substring(idx);
    }

    /**
     * Utility function to determine if we are running the project from the filesystem or not.
     *
     * @return {boolean} <cdoe>true</code> if we are running off the filesystem, else <code>false</code>
     */
    main.isFileSystem = function() {
        return document.location.toString().indexOf("file:///") == 0;
    }

    /**
     * Gets the appropriate base URI, depending on whether the application is running in from the filesystem or not.
     *
     * @return {String} the application's base URI
     * @throws {jsx3.lang.Exception} if an error occurs while calculating the gBaseURI
     */
    main.getGBaseURI = function() {
        try {
            var base = this.isFileSystem() ? this.getGBaseURIStatic() : (window.gBaseURI ? window.gBaseURI : "http:/localhost:8080");
            if (base.lastIndexOf("/") == (base.length - 1)) {
                base = base.substring(0, base.length - 1);
            }
            return base;
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.getGBaseURI");
            throw new jsx3.lang.Exception("Exception thrown while retrieving gBaseURI", jsx3.NativeError.wrap(ex));
        }
    }

    /**
     * Internal function to get the base URI of the application when running from the filesystem.  Called by the
     * <code>getGBaseURI</code> function.
     *
     * @return {String} the gBaseURI
     * @throws {jsx3.lang.Exception} if an error occurs while calculating the static gBaseURI
     * @private
     * @jsxobf-clobber
     */
    main.getGBaseURIStatic = function() {
        try {
            if (!this.gBaseURIStatic) {
                var loc = window.location.toString();
                var index = loc.lastIndexOf("?");
                if (index > -1) { // strip off any parameters after the html file...
                    loc = loc.substring(0, index);
                }
                loc = loc.substring(0, loc.lastIndexOf("/"));
                // strip off the html file, etc
                var user = this.getServer().resolveURI("jsxuser://") + "JSXAPPS/";
                var index2 = user.indexOf("../");
                while (index2 == 0) {
                    user = user.substring(3);
                    loc = loc.substring(0, loc.lastIndexOf("/"));
                    // strip off the html file, etc
                    index2 = user.indexOf("../");
                }
                this.gBaseURIStatic = loc + "/" + user;
            }
            return this.gBaseURIStatic;
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.getGBaseURIStatic");
            throw new jsx3.lang.Exception("Exception thrown while calculating the static gBaseURI", jsx3.NativeError.wrap(ex));
        }
    }

    main.setContextRootForNamespace = function(namespace, contextRoot) {
        try {
            this.contextRoots[namespace] = contextRoot;
        }
        catch (ex) {
            this.logException(ex, "Error in ux.megatron.Main.setContextRootForNamespace");
        }
    }

    /**
     * Given a plugin package's namespace, gets the contextRoot for that nemespace.
     *
     * @param namespace {String} the namespace of the plugin package
     *
     * @return {String} the contextRoot for the namespace
     *
     * @throws {ux.megatron.exception.InvalidNamespaceException} if the <code>namespace</code> argument is invalid
     * @throws {jsx3.lang.Exception} if an unknown error occurs while retrieving the contextRoot
     */
    main.getContextRootForNamespace = function(namespace) {
        if (!namespace) {
            throw new ux.megatron.exception.InvalidNamespaceException("The namespace is null or undefined");
        }
        if (typeof(namespace) != "string") {
            throw new ux.megatron.exception.InvalidNamespaceException("The namespace argument is not a string");
        }
        try {
            var ret = null;
            if (this.isFileSystem()) {
                ret = this.contextRoots[namespace];
                if (!ret) {
                    var index = namespace.lastIndexOf(".");
                    if (index > -1) {
                        ret = namespace.substring(index + 1);
                    }
                    else {
                        ret = namespace;
                    }
                    if (ret == "admin") {
                        ret = "cdbadmin";
                    }
                }
            }
            else {
                ret = this.contextRoots[namespace];
                if(ret === null) {
                    ret = adminContextRoot ? adminContextRoot : "cdbadmins";
                }
                if (namespace == "ux.megatron") {
                    ret += "/JSXAPPS/cdbadmin";
                }
            }
            return ret;
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.getContextRootForNamespace");
            throw new jsx3.lang.Exception("Unknown exception while retrieving the context root for namespace " + namespace, jsx3.NativeError.wrap(ex));
        }
    }

    /**
     * Gets a url that is resolved to the proper value for a static or live environment from for the current protocol
     * (file, http, etc.), given the desired resource path and the resource's plugin package's namespace.
     *
     * @param namespace {String | ux.megatron.util.component.ComponentConfig} the plugin package namespace of this
     *                  resource's plugin package, or the <code>ComponentConfig</code> of the component that owns the
     *                  resource at <code>relPath</code>
     * @param relPath {String} the path to the resource, relative to the plugin's context root
     *
     * @throws {ux.megatron.exception.InvalidNamespaceException} if <code>namespace</code> is invalid
     * @throws {jsx3.lang.Exception} if an unknown error occurs
     *
     * @return {String} the resolved URI
     */
    main.resolveURI = function(namespace, relPath) {
        try {
            var id = ux.megatron.util.Performance.beginBenchmark("Resolving URI for " + relPath);
            var ret = null;
            try {
                ret = ux.megatron.Main.getContextRootForNamespace(namespace) + "/";
                if(ret.length == 1)ret = "";
                if(ret !== null) {
                    if(ux.megatron.Main.isFileSystem()) {
                        ret = ux.megatron.Main.getGBaseURI() + "/" + ret + ((relPath.indexOf("/") == 0) ? relPath.substring(1) : relPath);
                    }
                    else {
                        ret = ret + main.getServer().resolveURI((relPath.indexOf("/") == 0) ? relPath.substring(1) : relPath);
                        //ret = "/" + ret + ((relPath.indexOf("/") == 0) ? relPath.substring(1) : relPath);
                    }
                }
            }
            catch(ex) {
                throw jsx3.NativeError.wrap(ex);
            }
            ux.megatron.util.Performance.endBenchmark(id);

            return ret;
        } catch(ex) {
            throw ex;
        }
    }

    /**
     * Loads an external resource into this server instance. What this method does depends on the <code>strType</code>
     * parameter.
     * <ul>
     *   <li><code>css</code> - Loads a CSS file asynchronously into the memory space of the page hosting this
     *       application; returns <code>null</code>.</li>
     *   <li><code>xml</code> or <code>xsl</code> - Loads an XML file synchronously into the XML cache of this
     *       application; <code>strId</code> is ignored; returns the loaded {jsx3.xml.Document} instance.</li>
     *   <li><code>jss</code> or <code>ljss</code> - Loads a dynamic properties file or localized properties bundle
     *       synchronously into this application; <code>strId</code> is ignored; returns <code>null</code>.</li>
     * </ul>
     *
     * @param strSrc {String} The path to the resource, relative to the context root of its owning component.
     * @param namespace {String | ux.megatron.util.component.ComponentConfig} the namespace of the plugin package
     *                  that the resource belongs to.
     * @param strId {String} the unique identifier of the resource. A resource loaded by this method may clobber
     *              a previously loaded resource of the same type and id.  This will be the id of the resource in the cache.
     * @param strType {String} the type of include, one of: <code>css</code>, <code>jss</code>, <code>xml</code>,
     *                <code>xsl</code>, or <code>ljss</code>.
     * @param bReload {boolean} if <code>true</code>, a CSS file is reloaded from the remote server without checking
     *                the local browser cache. Other types of resources are not affected by this parameter.
     * @return {jsx3.xml.Document | null} the return type depends on the <code>strType</code>
     *          parameter. See the method description.
     *
     * @throws {jsx3.lang.Exception} if an error occurs while loading the resource.
     */
    main.loadResource = function(strSrc, namespace, strId, strType, bReload) {
        try {
            if (!(strType == "css") && !(strType == "jss") && !(strType == "ljss") && !(strType == "xml") && !(strType == "xsl")) {
                throw new ux.megatron.exception.UnsupportedResourceTypeException(strType);
            }
            var id = ux.megatron.util.Performance.beginBenchmark("Loading resource " + strSrc);
            var absURI = this.resolveURI(namespace, strSrc, true);
            var ret = null;
            try {
                ret = this.getServer().loadInclude(absURI, strId, strType, bReload);
            }
            catch(failed) {
                try {
                    ux.megatron.Main.getServer().getCache().clearById(strId ? strId : absURI);
                }
                catch(innerfail) {
                    // do nothing
                }
            }
            ux.megatron.util.Performance.endBenchmark(id);
            return ret;
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.loadResource");
            if (main._sessionExpired())
                return;
            if (ex instanceof ux.megatron.exception.UnsupportedResourceTypeException) {
                throw ex;
            }
            else {
                throw new jsx3.lang.Exception("Could not load resource " + strSrc, jsx3.NativeError.wrap(ex));
            }
        }
    }

    /**
     * Loads one or more external resources specified in an external xml document into this server instance.
     * What this method does depends on various attributes defiend in xml document located at <code>strPath</code>  parameter
     *
     * <h3>Attribute namespace {String}:</h3>
     * <ul>
     *   <li>the namespace of the plugin packag that the resource belongs to. Will use parameter <code>namespace</code> as default</li>
     * </ul>
     * <h3>Attribute id {String}:</h3>
     * <ul>
     *   <li>the unique identifier of the resource. A resource loaded by this method may clobber
     *       a previously loaded resource of the same type and id.  This will be the id of the resource in the cache.
     *       Will use parameter <code>strPath</code> as default </li>
     * </ul>
     * <h3>Attribute type:</h3>
     * <h3>Attribute type:</h3>
     * <ul>
     *   <li><code>script</code> - Given the absolute path to the .js file, or the relative path and it's plugin component's
     *       namespace, retrieves the .js file from the server, and loads the class.</li>
     *   <li><code>css</code> - Loads a CSS file asynchronously into the memory space of the page hosting this
     *       application.</li>
     *   <li><code>xml</code> or <code>xsl</code> - Loads an XML file synchronously into the XML cache of this
     *       application.</li>
     *   <li><code>jss</code> or <code>ljss</code> - Loads a dynamic properties file or localized properties bundle
     *       synchronously into this application.</li>
     * </ul>
     * <h3>Sample of a resource.xml file:</h3>
     *
     * <code>
     * &lt;data jsxid=&quot;jsxroot&quot;&gt;<br />
     * &nbsp;&nbsp;&nbsp;&nbsp;&lt;record jsxid=&quot;1&quot; path=&quot;ux/megatron/enterpriseAssets/envDef/envDtls/genInfo/jss/genInfo_en.xml&quot; id=&quot;&quot; type=&quot;jss&quot; namespace=&quot;ux.megatron&quot;/&gt;<br />
     * &nbsp;&nbsp;&nbsp;&nbsp;&lt;record jsxid=&quot;2&quot; path=&quot;ux/megatron/enterpriseAssets/envDef/envDtls/genInfo/GenInfo.js&quot; type=&quot;script&quot;  /&gt;<br />
     * &nbsp;&nbsp;&nbsp;&nbsp;&lt;record jsxid=&quot;2&quot; path=&quot;ux/megatron/enterpriseAssets/envDef/envDtls/genInfo/GenInfoAdd.js&quot; type=&quot;script&quot;  /&gt;<br />
     * &lt;/data&gt;
     * </code>
     *
     * @param strPath {String} The path to the xml document, relative to the context root of its owning component.
     * @param namespace {String | ux.megatron.util.component.ComponentConfig} the namespace of the plugin package that the resource belongs to.
     *
     * @throws {jsx3.lang.IllegalArgumentException} if the caller of this function does not pass arguments according to the method's contract.
     *
     * @throws {ux.megatron.exception.InvalidXMLDocException} if xml document located in <code>strPath</code> is invalid or not found.
     *
     * @throws {jsx3.lang.Exception} if an error occurs while loading one of the the resources specified in <code>strPath</code..
     */
    main.loadResources = function(strPath, namespace) {
        var absURI, resDocument, nodeList, next, path, strId, type ;

        try {
            absURI = main.resolveURI(namespace, strPath)
        }
        catch(e) {
            throw new jsx3.lang.IllegalArgumentException("\nstrPath = " + strPath + "\nnamespace = " + namespace, jsx3.NativeError.wrap(e));
        }
        try {
            resDocument = jsx3.xml.CDF.Document.newDocument();
            resDocument.setAsync(false);
            resDocument.setValidateOnParse(true)
            resDocument = resDocument.load(absURI);
            if (resDocument.getError().code != 0) {
                throw  resDocument
            }
            nodeList = resDocument.selectNodes("//record");
        }
        catch(e) {
            if (main._sessionExpired())
                return;
            throw new ux.megatron.exception.InvalidXMLDocException("\nPlease check if " + absURI + " exists and is a valid document.", jsx3.NativeError.wrap(e));
        }
        try {
            var strNamespace = namespace ;
            for (i = 0; i < nodeList.size(); i++) {
                next = nodeList.get(i);
                path = next.getAttribute("path");
                type = next.getAttribute("type");
                strNamespace = next.getAttribute("namespace")
                if (!strNamespace || strNamespace == "") {
                    strNamespace = namespace
                }
                if (next.getAttribute("type") == "script") {
                    try {
                        main.loadClass(path, strNamespace)
                    }
                    catch(e) {
                        throw e;
                    }
                }
                if (type == "jss" || type == "ljss" || type == "xml" || type == "xsl" || type == "css") {
                    strId = (strId = next.getAttribute("strId")) ? strId : path;
                    main.getServer().loadInclude(main.resolveURI(strNamespace, path), strId, type, false);
                }
            }
        }
        catch(e) {
            if (main._sessionExpired())
                return;
            throw new jsx3.lang.Exception("Could not load resource .\nCan't load one or more resources located in document  " + absURI, jsx3.NativeError.wrap(e));
        }
    }

   /**
     * Pre loads a particular serialized UI resource into cache, automatically resolving URLs within the
     * Admin UI plugin framework. Is used for ACL to test if user has access right to the UI
     *
     * @param namespace {String | ux.megatron.util.component.ComponentConfig} the namespace of the resource's plugin
     *                  package, or the <code>ComponentConfig</code> for the component that owns this UI Resource
     * @param resourcePath {String} the path (relative to the component path of the plugin component) of the
     *                     resource to be loaded into <code>parent</code>
     * @throws {jsx3.lang.Exception} if an error occurs while loading the resource
     *
     * @private
     *
     * @return {int} HTTP response code (i.e., 200 OK , 404 Not Found, 500 Internal Server Error, 403 Forbidden etc);
     */
    main.preLoadUIResource = function(namespace, resourcePath) {
        ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#preLoadUIResource: resourcePath = " + resourcePath)
        try {
            var loadedstatus = 0;
            if (namespace == "ux.megatron") {
                var prefix = "JSXAPPS/cdbadmin/"
                resourcePath = resourcePath.replace(prefix, "")
            }
            var absPath = this.resolveURI(namespace, resourcePath);
            var req = new jsx3.net.Request();
            if (ux.megatron.Main.isFileSystem()) {
                req.open("GET", absPath, false);
            }
            else {
                ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#preLoadUIResource Runinig at server.\npath = " + absPath)
                req.open("GET", strpath, false);
            }
            req.send();
            objXML = req.getResponseXML()
            ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#preLoadUIResource: HTTP response code  = " + req.getStatus())
            loadedstatus = req.getStatus()
            if (loadedstatus == 200) {
                main.getServer().getCache().setDocument(absPath, objXML);
            }
            else {
                if (main._sessionExpired()) {
                    return null;
                }
                if (loadedstatus == 500) {
                    ux.megatron.Main.getServer().alert("500", req.getResponseText(),null,"Ok",{width:600,height:400})
                }
            }
            return loadedstatus

        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.loadUIResource");
            if (main._sessionExpired())
                return;
            throw new jsx3.lang.Exception("Error loading UI Resource " + resourcePath + " with namespace " + namespace, jsx3.NativeError.wrap(ex));
        }
    }

    /**
     * Loads a particular serialized UI resource into a parent block, automatically resolving URLs within the
     * Admin UI plugin framework.
     *
     * @param parent {jsx3.app.Model} the Model object representing the parent object to load the resource as
     *               a child of.
     * @param namespace {String} the namespace of the resource's plugin package for the component that owns this UI Resource
     * @param resourcePath {String} the path (relative to the component path of the plugin component) of the
     *                     resource to be loaded into <code>parent</code>
     * @param repaint {boolean} flag to indicate whether or not to repaint the parent after the child is loaded. Default
     *                is <code>false</code> (no repaint)
     *
     * @throws {jsx3.lang.Exception} if an error occurs while loading the resource
     *
     * @return {jsx3.app.Model} The deserialized object that was loaded into <code>parent</code>
     */
    main.loadUIResource = function(parent, namespace, resourcePath, repaint) {
        ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#loadUIResource: resourcePath = " + resourcePath)
        try {
            var absPath = this.resolveURI(namespace, resourcePath);
            var objXML = this.getServer().getCache().getDocument(absPath)
            if (objXML == null) {
                var req = new jsx3.net.Request();
                if (ux.megatron.Main.isFileSystem()) {
                    req.open("GET", absPath, false);
                }
                else {
                    ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#loadUIResource Runinig at server.\npath = " + absPath)
                    req.open("GET", absPath, false);
                }
                req.send();
                objXML = req.getResponseXML()
                ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#loadUIResource: HTTP response code  = " + req.getStatus())
                if (req.getStatus() != 200) {
                    if (main._sessionExpired()){
                        return null;
                    }
                    if(req.getStatus() == 500){
                        ux.megatron.Main.getServer().alert("500",req.getResponseText(),null,"Ok",{width:600,height:400})
                    }
                }
                main.getServer().getCache().setDocument(absPath, objXML);
            }
            return parent.loadXML(objXML, repaint);
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.loadUIResource");
            if (main._sessionExpired())
                return;
            throw new jsx3.lang.Exception("Error loading UI Resource " + resourcePath + " with namespace " + namespace, jsx3.NativeError.wrap(ex));
        }
    }

    /**
     * Asynchronously loads a particular serialized UI resource into a parent block, automatically resolving URLs within the
     * Admin UI plugin framework. Notifies the caller of the completed load on the <code>callbackTarget</code>'s
     * <code>callbackFunction</code> function.  The callback will pass an object with a <code>resourcePath</code> field, which will
     * have the original <code>resourcePath</code> specified here, a <code>namespace</code> field conaining the original
     * <code>namespace</code> specified here, a <code>status</code> field with a String value of either
     * <code>SUCCESS</code> or <code>FAILURE</code>, a <code>message</code> field containing any error message, an <code>exception</code>
     * field, containing any {jsx3.lang.Exception} thrown, and an <code>obj</code> field containing the
     * deserialized {jsx3.app.Model} object that was loaded.
     *
     * If you need asynchronous loading of components, but chanied to guarantee the order in which they are loaded, load
     * successive components from the callbackFunction.  This synchronizes the loading of multiple UI files, but allows
     * the rest of the application to continue to work (repainting, etc). rather than waiting for the UI objects to load before
     * coninuing.
     *
     * @param parent {jsx3.app.Model} the Model object representing the parent object to load the resource as
     *               a child of.
     * @param namespace {String | ux.megatron.util.component.ComponentConfig} the namespace of the resource's plugin package
     *                  or the <code>ComponentConfig</code> for the component that owns this UI Resource
     * @param resourcePath {String} the path (relative to the component path of the plugin component) of the
     *                     resource to be loaded into <code>parent</code>
     * @param repaint {boolean} flag to indicate whether or not to repaint the parent after the child is loaded. Default
     *                is <code>false</code> (no repaint)
     * @param callbackTarget {Object} the target object on which the callback to <code>callbackFunction</code> should be made
     *                       when the load operation is complete.
     * @param callbackFunction {Function} the function to call on <code>callbackTarget</code> to perform the callback once
     *                         the load operation is complete.
     *
     * @throws {ux.megatron.exception.InvalidTargetException} if <code>callbackTarget</code> and <code>callbackFunction</code>
     *         are specified, but the <code>callbackTarget</code> is not an Object
     * @throws {ux.megatron.exception.InvalidFunctionException} if <code>callbackTarget</code> and <code>callbackFunction</code>
     *         are specified, but <code>callbackFunction</code> is not a function
     * @throws {jsx3.lang.Exception} if an unknown error occurs
     */
    main.loadUIResourceAsync = function(parent, namespace, resourcePath, callbackTarget, callbackFunction, repaint) {
        ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#loadUIResourceAsync: resourcePath = " + resourcePath)
        try {
            if (!parent) {
                throw new jsx3.lang.Exception("Parent is not defnied.  Cannot load UI Resource into non-existent parent");
            }
            if (callbackTarget && callbackFunction) {
                if (typeof(callbackTarget) != "object") {
                    throw new ux.megatron.exception.InvalidTargetException("Specified callback target is not an Object");
                }
                else if (typeof(callbackFunction) != "function") {
                    throw new ux.megatron.exception.InvalidFunctionException("Specified callback function is not a function");
                }
            }
            var absPath = this.resolveURI(namespace, resourcePath);
            var objXML = this.getServer().getCache().getDocument(absPath)
            if (objXML != null) {
                jsx3.sleep(function() {
                    ux.megatron.util.Log.SYSTEM.info("loadUIResourceAsync loading from cache ")
                    var msg = new Object();
                    msg.obj = parent.loadXML(objXML, true);
                    msg.resourcePath = resourcePath;
                    msg.namespace = namespace;
                    msg.headers = null;
                    msg.exception = null;
                    msg.status = "SUCCESS";
                    msg.message = "Successfully loaded UI Resource " + resourcePath + " from cache";
                    if (callbackTarget && callbackFunction) {
                        setTimeout(function() {
                            callbackFunction.call(callbackTarget, msg);
                        }, 0);
                    }
                }, null, main);
            }
            else {
                ux.megatron.util.Log.SYSTEM.info("loadUIResourceAsync loading from servlet ")
                var req = new jsx3.net.Request();
                req.parent = parent;
                req.repaint = repaint;
                req.resourcePath = resourcePath;
                req.namespace = namespace;
                req.callbackTarget = callbackTarget;
                req.callbackFunction = callbackFunction;
                req.absPath = absPath ;
                if (ux.megatron.Main.isFileSystem()) {
                    req.open("GET", absPath, true);
                }
                else {
                    ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#loadUIResourceAsync Runinig at server.\npath = " + absPath)
                    req.open("GET", absPath, true);
                    ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#loadUIResourceAsync invoked open");
                }
                req.subscribe(jsx3.net.Request.EVENT_ON_RESPONSE, main.onLoadUIResourceResponse);
                req.subscribe(jsx3.net.Request.EVENT_ON_TIMEOUT, main.onLoadUIResourceTimeout);
                req.send(null, 10000);
            }
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.loadUIResourceAsync")
            if ((ex instanceof ux.megatron.exception.InvalidTargetException) || (ex instanceof ux.megatron.exception.InvalidFunctionException)) {
                throw ex;
            }
            else {
                throw new jsx3.lang.Exception("Unknown error occurred while trying to asynchronously load UI Resource " + resourcePath + " with namespace " + namespace, jsx3.NativeError.wrap(ex));
            }
        }
    }

    /**
     * Private function to handle a response from a <code>loadUIResource()</code> call.
     *
     * @param objEvent {Object} the response message object from the subscription callback
     *
     * @private
     * @jsxobf-clobber
     */
    main.onLoadUIResourceResponse = function(objEvent) {
        ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#onLoadUIResourceResponse Call back function for async loading objEvent " + objEvent)
        try {
            var req = objEvent.target;
            ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#onLoadUIResourceResponse. status for request " + req + "is "+req.getStatus())
            var msg = new Object();
            msg.resourcePath = req.resourcePath;
            msg.namespace = req.namespace;
            msg.headers = req.getAllResponseHeaders();
            if (req.getStatus() == "200") {
                msg.exception = null;
                msg.status = "SUCCESS";
                msg.message = "Successfully loaded UI Resource " + req.resourcePath;
                try {
                    msg.obj = req.parent.loadXML(req.getResponseXML(), true);
                    try {
                        main.getServer().getCache().setDocument(req.absPath , req.getResponseXML());
                    } catch(failed) {
                        try {
                            ux.megatron.Main.getServer().getCache().clearById(req.absPath);
                        }
                        catch(innerfail) {
                            // do nothing
                        }
                    }
                } catch (ex) {
                    if (main._sessionExpired())
                        return;
                    msg.status = "FAILURE";
                    msg.exception = jsx3.NativeError.wrap(ex);
                    msg.message = "Successfully retrieved UI Resource " + req.resourcePath + " but failed to load it into the parent object\nException thrown: " + msg.exception.getMessage();
                    main.logException(ex);
                }
            }
            else {
                if (main._sessionExpired())
                    return;
                msg.exception = null;
                msg.status = "FAILURE";
                msg.obj = null;
                msg.message = "Failed to load UI Resource " + req.resourcePath + "\nHTTP Response Code: " + req.getStatus() + "\nHTTP Response Text: " + req.getStatusText();
                if (req.getStatus() == 500) {
                    ux.megatron.Main.getServer().alert("500", req.getResponseText(),null,"Ok",{width:600,height:400})
                }
            }
            if (req.callbackTarget && req.callbackFunction) {
                setTimeout(function() {
                    req.callbackFunction.call(req.callbackTarget, msg);
                }, 0);
            }
        } catch(ex) {
            ux.megatron.util.Log.SYSTEM.error("Error in ux.megatron.Main.onLoadUIResourceResponse 0" + ex)
            if (main._sessionExpired())
                return;
            main.logException(ex, "Error in ux.megatron.Main.onLoadUIResourceResponse")
            if (req.callbackTarget && req.callbackFunction) {
                msg.exception = ex;
                msg.status = "FAILURE";
                msg.message = "Failed to load UI Resource " + req.resourcePath;
                if (req.callbackTarget && req.callbackFunction) {
                    setTimeout(function() {
                        req.callbackFunction.call(req.callbackTarget, msg);
                    }, 0);
                }
            }
            if (objEvent.target.getStatus() == 500) {
               ux.megatron.Main.getServer().alert("500", objEvent.target.getResponseText(),null,"Ok",{width:600,height:400})
            }
        }
    }

    /**
     * Private function to handle a timeout on a <code>loadUIResource()</code> call.
     *
     * @param objEvent {Object} the response message object from the subscription callback
     *
     * @private
     * @jsxobf-clobber
     */
    main.onLoadUIResourceTimeout = function(objEvent) {
        try {
            if (main._sessionExpired())
                return;
            var req = objEvent.target;
            var msg = new Object();
            msg.resourcePath = req.resourcePath;
            msg.namespace = req.namespace;
            msg.headers = req.getAllResponseHeaders();
            msg.exception = null;
            msg.status = "FAILURE";
            msg.obj = null;
            msg.message = "Failed to load UI Resource " + req.resourcePath + "\nOperation Timed Out";
            if (objEvent.target.getStatus() == 500) {
               ux.megatron.Main.getServer().alert("500", objEvent.target.getResponseText(),null,"Ok",{width:600,height:400})
            }
            if (req.callbackTarget && req.callbackFunction) {
                setTimeout(function() {
                    req.callbackFunction.call(req.callbackTarget, msg);
                }, 0);
            }
        } catch(ex) {
            main.logException(ex, "Error in ux.megatron.Main.onLoadUIResourceTimeout")
            if (main._sessionExpired())
                return;
            if (req.callbackTarget && req.callbackFunction) {
                msg.exception = ex;
                msg.status = "FAILURE";
                if (req.callbackTarget && req.callbackFunction) {
                    setTimeout(function() {
                        req.callbackFunction.call(req.callbackTarget, msg);
                    }, 0);
                }
            }
        }
    }

    /**
     * Loads and parses a mapping rules file synchronously; returns a new instance of {ux.megatron.net.Service}.
     *
     * @param namespace {String | ux.megatron.util.component.ComponentConfig} the namespace of the plugin package that the resource belongs to.
     * @param strRulesURL {String} The relative URI for the rules document (a CXF document).
     * @param strOperationName {String} name of operation to call.
     * @param strPOIOperationName {String} name of process operation indicator.
     * @param callerInstanceId {String} (optional) a unique identifier for the instance of the caller. Ids are automatically generated
     *                    to uniquely identify the calling class/function for service calls to a given rules file/operation,
     *                    and ignore responses from earlier (stale) requests.  This is not able identify unique <i>instances</i>
     *                    of the calling class, however.  If you may have multiple instance of the same class, this handling
     *                    of stale requests must be done on an <i>instance</i> basis.  This parameter allows you to specify
     *                    an id for the unique instance of the calling class.
     * @param bNoCancelOnNew {boolean} if <code>true</code>, multiple requests for the same rules file/operation from the same
     *                    calling location will all be used (responses from earlier requests will not be ignored). (Default
     *                    value is <code>false</code>.
     *
     * @return {ux.megatron.net.Service} the service object that has been loaded.
     *
     * @throws {jsx3.lang.Exception} if an error occurs while creating the service object
     */
    main.loadService = function(namespace, strRulesURL, strOperationName, strPOIOperationName, callerInstanceId, bNoCancelOnNew) {
        try {
            jsx3.require("jsx3.net.Service");
            var objService = (new ux.megatron.net.Service(ux.megatron.Main.resolveURI(namespace, strRulesURL), strOperationName, strPOIOperationName, callerInstanceId, bNoCancelOnNew)).setNamespace(main.getServer());
            objService.setOutboundStubURL("jsx://xml/stubs/soap.xml")
            var stub = objService.getInboundURL()
            if (!ux.megatron.Main.getServer().getEnv("MODE")) {
                if (!stub) {
                    ux.megatron.util.Log.SERVICE.warn("System is running in static mode.\n Stub url for the mapping rule " + strOperationName + " specified at " + strRulesURL + " is " + stub);
                }
                else {
                    var absuri = ux.megatron.Main.resolveURI(namespace, stub)
                    ux.megatron.util.Log.SYSTEM.info("ux.megatron.Main#loadService: \n absolute path to mapping rule is " + absuri)
                    objService.setInboundURL(absuri);
                }
            }
            return  objService;
        }
        catch(e) {
            main.logException(e, "Error in ux.megatron.Main.loadService");
            throw new jsx3.lang.Exception("Error creating service object for rules file " + strRulesURL, jsx3.NativeError.wrap(e));
        }
    }

    /**
     * Given the absolute path to the .js file, or the relative path and it's plugin component's
     * namespace, retrieves the .js file from the server, and loads the class.
     *
     * @param path {String} either an absolute URL to the .js file (<code>namespace</code> MUST not be
     *            specified), or a relative path to the .js file (<code>namespace</code> MUST be specified, and must be
     *            the plugin package namespace for the class' plugin).
     * @param namespace {String | ux.megatron.util.component.ComponentConfig} the plugin package namespace for the class'
     *                  plugin package, or the <code>ComponentConfig</code> for the component that owns this class.
     *                  Used to resolve the path to the .js file, given the class name specified in <code>path</code>.
     *                  (Must be <code>null</code> if <code>path</code> is an absoulte url to the .js file).
     *
     * @throws {ux.megatron.exception.LoadClassFailedException} if an error occurs while loading the class.
     */
    main.loadClass = function(path, namespace) {
        try {
            var id = ux.megatron.util.Performance.beginBenchmark("Loading class " + path);
            if (path.indexOf("://") < 0) {
                if (namespace) {
                    var fullpath = this.resolveURI(namespace, path, true);
                    this._loadClass(fullpath);
                }
                else {
                    throw new ux.megatron.exception.InvalidURIException(path + " is an invalid URI.  An absoulte path was expected because the namespace argument was null or undefined");
                }
            }
            else {
                this._loadClass(path);
            }
            ux.megatron.util.Performance.endBenchmark(id);
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main.loadClass");
            throw new ux.megatron.exception.LoadClassFailedException("Load Class failed for path " + path + " and namespace " + namespace, jsx3.NativeError.wrap(ex));
        }
    }

    /**
     * Given the absolute URL to a class' .js file, retrieves the .js file from the server, and loads the class
     * into the browser's memory for the current page.
     *
     * @param absPath {String} the absolute URL to the class to be loaded.
     *
     * @throws {ux.megatron.exception.LoadClassFailedException} if an error occurs while loading the class.
     *
     * @private
     * @jsxobj-clobber
     */
    main._loadClass = function(absPath) {
        try {
            var req = new jsx3.net.Request();
            req.open("GET", absPath, false);
            var myreq = req.send();
            var content = req.getResponseText();
            if (req.getStatus() != 200) {
                throw "Status is " + req.getStatus();
            }
            else if (!content) {
                throw "ResponseText is null";
            }
            else if (content.indexOf("Matrix_cdbadmin_Login_Test_For_SessionTimeOut") != -1) {
                //TODO:: by Eric
                throw "Matrix_cdbadmin_Login_Test_For_SessionTimeOut is loaded. Not a valid Java Script";
            }
            jsx3.eval(content);
        } catch(ex) {
            this.logException(ex, "Error in ux.megatron.Main._loadClass");
            if (main._sessionExpired())
                return;
            throw new ux.megatron.exception.LoadClassFailedException("Load Class failed class at absolute path " + absPath, jsx3.NativeError.wrap(ex));
        }
    }

    /**
    * Checks to see if the current session has expired, and redirects the user to the login page if it has.
    *
    * @private
    */
    main._sessionExpired = function() {
        if (ux.megatron.Main.getServer().getEnv("MODE")) {
            if (ux.megatron.util.ServiceHelper.sessionExpired()) {
                ux.megatron.util.Log.SERVICE.warn("ux.megatron.Main#_sessionExpired: session is expired");
                ux.megatron.util.ServiceHelper.redirectToLoginPage();
                return true;
            }
        }
        return false;
    }

   // todo: Remove main._setSystemLocale once this GI bug is fixed.
   /**
     * Internal function. Due to a bug in GI 3.5 the property bundles in addin will not load.
     * This function quarantines that the property bundle addins\MatrixAdmin\jss\adminJSS.xml
     * is loaded properly.
     * @private
     * @jsxobf-clobber
     */
    main._setSystemLocale = function() {
        //alert(ux.megatron.Matrix.ADDIN.resolveURI("jss/adminJSS.xml") )
        main.pb = jsx3.app.PropsBundle.getProps(ux.megatron.ADDIN.resolveURI("jss/adminJSS.xml"), null, jsx3.getSystemCache());
        jsx3.System.LJSS.addParent(main.pb);
    }

    main._setSystemLocale();


    // todo: Remove main._setLocale once this GI bug is fixed.
    /**
     * Internal function. Due to a bug in GI 3.5 the property bundles in addin will not load.
     * This function quarantines that the appropriate language of the property bundle
     * addins\MatrixAdmin\jss\adminJSS.xml is loaded properly.
     * Use this function only if the user can interact with the interface to change the system language to a preferred language
     *
     * @param newLocale {jsx3.util.Locale} new Locale
     */
    main.setLocale = function(newLocale) {
        jsx3.System.LJSS.removeParent(main.pb);
        main.pb = jsx3.app.PropsBundle.getProps(ux.megatron.ADDIN.resolveURI("jss/adminJSS.xml"), newLocale, jsx3.getSystemCache());
        jsx3.System.LJSS.addParent(main.pb);
    }
	
	/**
	* load and return cdf xml.
	*/
    main.loadXML = function(strPath, namespace) {
        var absURI, resDocument;

        try {
            absURI = main.resolveURI(namespace, strPath)
        }
        catch(e) {
            throw new jsx3.lang.IllegalArgumentException("\nstrPath = " + strPath + "\nnamespace = " + namespace, jsx3.NativeError.wrap(e));
        }
        try {
            resDocument = jsx3.xml.CDF.Document.newDocument();
            resDocument.setAsync(false);
            resDocument.setValidateOnParse(true)
            resDocument = resDocument.load(absURI);
            if (resDocument.getError().code != 0) {
                throw  resDocument;
            }
        }
        catch(e) {
            if (main._sessionExpired())
                return null;
            throw new ux.megatron.exception.InvalidXMLDocException("\nPlease check if " + absURI + " exists and is a valid document.", jsx3.NativeError.wrap(e));
        }
		return resDocument;
    }

    //Some simple functions attached to jsx3;
    jsx3.require("jsx3.gui.Block");
    jsx3.gui.Block.prototype.hide = function(paint) {
        paint = paint || true;
        this.setDisplay(jsx3.gui.Block.DISPLAYNONE,paint);
        return this;
    };

    jsx3.gui.Block.prototype.show = function(paint) {
        paint = paint || true;
        this.setDisplay(jsx3.gui.Block.DISPLAYBLOCK,paint);
        return this;
    };

    jsx3.gui.Block.prototype.get = function(name) {
        return this.getDescendantOfName(name);
		if(_obj == null || typeof(_obj) == 'undefined')
			throw new jsx3.lang.IllegalArgumentException("\nname =" + name, "target element is not exist!");
    };

    jsx3.gui.Block.prototype.enable = function(paint) {
        paint = paint || true;
        if(this.setEnabled && this.getEnabled() != jsx3.gui.Form.STATEENABLED) 
            this.setEnabled(jsx3.gui.Form.STATEENABLED, paint);
        return this;
    };

    jsx3.gui.Block.prototype.disable = function(paint) {
        paint = paint || true;
        if(this.setEnabled && this.getEnabled() != jsx3.gui.Form.STATEDISABLED) 
            this.setEnabled(jsx3.gui.Form.STATEDISABLED, paint);
        return this;
    };

});
